<!--
 * @title:
 * @params1: 参数1
 * @params2: 参数2
 * @params3: 参数3
 * @params4: 参数4
 * @method1: 参数1
 * @method1: 参数2
 * @method1: 参数3
 * @method1: 参数4
 * @description: 全日历组件，带多种视图
 * @fileName: calendar.vue
 * @author: zhanglongfei
 * @date: 2020-10-28 11:13:07
!-->
<template>
  <div class="tl-full-calendar">
    <FullCalendar ref="calendar" :options="calendarOptions" />
  </div>
</template>

<script>
import FullCalendar from '@fullcalendar/vue' // vue核心组件
import dayGridPlugin from '@fullcalendar/daygrid' // 视图模式dayGridMonth, dayGridWeek, dayGridDay, dayGrid
import timeGridPlugin from '@fullcalendar/timegrid' // 视图模式timeGridWeek, timeGridDay, timeGrid
import listPlugin from '@fullcalendar/list' // 视图模式listYear, listMonth, listWeek, listDay, list
// import timeLinePlugin from '@fullcalendar/timeline' // 视图模式timelineYear, timelineMonth, timelineWeek, timelineDay, timeline
import interactionPlugin, { Draggable } from '@fullcalendar/interaction' // 一些交互
import { formatDate } from '@tapui/utils/date'

import { calendar as calendarDate } from '@/utils/calendar'
export default {
  name: 'TlCalendar',
  components: {
    FullCalendar
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin],
        initialView: 'dayGridMonth',
        // 授权码卧槽
        // schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
        // 汉化
        buttonText: {
          today: '今天',
          month: '月',
          week: '周',
          day: '日',
          list: '列表'
        },
        allDayText: '全天',
        headerToolbar: false,
        // 自定义按钮
        // customButtons: {
        //   refresh: {
        //     text: '刷新',
        //     click: this.refresh
        //   }
        // },
        // headerToolbar: {
        //   left: 'prev,next today',
        //   center: 'title',
        //   right: 'refresh dayGridMonth,timeGridWeek,timeGridDay,listWeek'
        // },
        // true:每月固定显示6周
        fixedWeekCount: false,
        // 是否显示周数
        weekNumbers: false,
        weekText: '周',
        // 周一为每周第一天
        firstDay: 1,
        dayCellContent: function(arg) {
          // 显示阴历和过节
          let str = arg.dayNumberText.replace('日', '')
          let date = calendarDate.solar2lunar(arg.date.getFullYear(), arg.date.getMonth() + 1, arg.date.getDate())
          let idate = date.IDayCn
          if (idate === '初一') {
            idate = date.IMonthCn
          }
          if (date.festival) {
            idate = date.festival
          } else if (date.lunarFestival) {
            idate = date.lunarFestival
          } else if (date.Term) {
            idate = date.Term
          }
          str = '<span class="idate">' + idate + '</span>' + str
          str = '<a class="fc-daygrid-day-number" data-navlink="{&quot;date&quot;:&quot;' + date.date + '&quot;,&quot;type&quot;:&quot;day&quot;}" tabindex="0">' + str + '</a>'
          return { html: str }
        },
        // 工作日和时间定义
        businessHours: [
          {
            daysOfWeek: [1, 2, 3, 4, 5, 6], // 周一 - 周六
            startTime: '08:30', // 上午8:30上班
            endTime: '12:00' // 中午12点吃饭
          },
          {
            daysOfWeek: [1, 2, 3, 4, 5, 6], // 周一 - 周六
            startTime: '13:30', // 下午13:30起床
            endTime: '18:00' // 下午18点下班
          }
        ],
        // 自动根据外部元素大小设置日历大小
        height: '100%',
        // 是否显示指示当前时间的标记，默认false。当用户查看日历时，指示器会自动重新定位。
        nowIndicator: true,
        // 中文
        locale: 'zh-cn',
        // 日历事件中展示的日期格式
        eventTimeFormat: {
          // like '14:30:00'
          hour: '2-digit',
          minute: '2-digit',
          hour12: false
        },
        // 显示为星期几的样子，默认是周几
        dayHeaderFormat: this.formatTimeShow,
        // dayHeaderFormat: {
        //   weekday: 'long'
        // },
        // 当事件太多时，会显示一个看起来像“+ 2更多”的链接
        dayMaxEventRows: true,
        // 当用户点击“更多”链接时发生的动作，支持"popover", "week", "day", view name, function。
        moreLinkClick: 'popover',
        // 事件显示方式
        eventDisplay: 'block',
        // 显示时间间隔，1小时
        slotDuration: '00:30:00',
        slotLabelInterval: { hours: 1 },
        // 每天的时间，从哪里开始显示，只是滚动到这里，不隐藏，隐藏用slotMinTime和slotMaxTime
        scrollTime: '08:00:00',
        // 日视图中，左侧时间显示方式
        slotLabelFormat: function(date) {
          return `${(date.date.hour < 10 ? '0' : '') + date.date.hour}:${(date.date.minute < 10 ? '0' : '') + date.date.minute}`
        },
        // 日和周可点击
        navLinks: true,
        // 下面三个属性，让事件可以拖动
        editable: true,
        droppable: true,
        eventDrop: this.eventDrop,
        eventResize: this.eventResize,
        events: this.eventSearch,
        // 日期点击
        dateClick: this.dateClick,
        // 事件点击
        eventClick: this.eventClick,
        eventMouseEnter: this.eventMouseEnter,
        eventMouseLeave: this.eventMouseLeave,
        datesSet: this.datesSet
      }
    }
  },
  // props: {
  //   events: {
  //     type: Array,
  //     default: function() {
  //       return []
  //     }
  //   }
  // },
  methods: {
    dateClick(info) {
      info.jsEvent.preventDefault()
      this.$emit('dateClick', info)
    },
    eventClick(info) {
      info.jsEvent.preventDefault()
      this.$emit('eventClick', info)
    },
    eventMouseEnter(info) {
      this.$emit('eventMouseEnter', info)
    },
    eventMouseLeave(info) {
      this.$emit('eventMouseLeave', info)
    },
    eventSearch(info, successCallback, failureCallback) {
      this.$emit('eventSearch', info, successCallback, failureCallback)
    },
    eventDrop(dropInfo) {
      this.$emit('eventTimeChange', dropInfo)
    },
    eventResize(dropInfo) {
      this.$emit('eventTimeChange', dropInfo)
    },
    datesSet(dateInfo) {
      this.$emit('datesSet', dateInfo)
    },
    refresh() {
      this.$refs.calendar.getApi().refetchEvents()
    },
    dayFormat(date) {
      return 'dsfa'
    },
    /** 格式化日期显示 */
    formatTimeShow(date) {
      if (this.$refs.calendar.getApi().view.type === 'timeGridWeek') {
        let currentDate = new Date(date.date.year + '-' + (date.date.month + 1) + '-' + parseInt(date.date.day)).getDay()
        return `${this.formatWeek(currentDate)}(${date.date.month + 1 + '-' + parseInt(date.date.day)})`
      } else {
        let currentDate = new Date(date.date.year + '-' + (date.date.month + 1) + '-' + parseInt(date.date.day)).getDay()
        return this.formatWeek(currentDate)
      }
    },
    formatWeek(days) {
      switch (days) {
        case 1:
          days = '星期一'
          break
        case 2:
          days = '星期二'
          break
        case 3:
          days = '星期三'
          break
        case 4:
          days = '星期四'
          break
        case 5:
          days = '星期五'
          break
        case 6:
          days = '星期六'
          break
        case 0:
          days = '星期日'
          break
      }
      return days
    }
  }
}
</script>

<style lang="scss">
.calendar-container {
  .fc .fc-button-primary:not(:disabled):active:focus,
  .fc .fc-button-primary:not(:disabled).fc-button-active:focus {
    -webkit-box-shadow: 0 0 0 0rem;
    box-shadow: 0 0 0 0rem;
  }
  .fc-h-event .fc-event-time {
    min-width: 36px;
  }
  .idate {
    font-size: 0.8em;
    margin-right: 5px;
    color: #aaa;
  }
}
</style>
